package com.ticket.sass.provider.service;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 朱其鹏
 */
public interface BaseService<T> extends IService<T> {
    default Long countByIds(List<Long> checkIds){
        if (checkIds == null || checkIds.size() == 0){
            return 0l;
        }
        return this.count(new QueryWrapper<T>().in("id", checkIds));
    }
    
    default <U extends PageInput> IPage<T> iPage(U input) {
        if (Objects.isNull(input)) {
            return null;
        }
        
        // 创建 Page 对象
        Page<T> page = new Page<>(input.getPageNum(), input.getPageSize());
        
        // 创建 QueryWrapper 对象
        QueryWrapper<T> queryWrapper = buildQueryWrapper(this.getEntityClass(), input);
        
        // 在此根据需要添加其他查询条件
        queryWrapper.orderByDesc("id");
        
        // 调用 this.page 方法
        return this.page(page, queryWrapper);
    }
    
    
    default <U extends PageInput> IPage<T> iPage(Class<T> entityClass, U input) {
        if (Objects.isNull(input)) {
            return null;
        }
        
        // 创建 Page 对象
        Page<T> page = new Page<>(input.getPageNum(), input.getPageSize());
        
        // 创建 QueryWrapper 对象
        QueryWrapper<T> queryWrapper = buildQueryWrapper(entityClass, input);
        
        // 在此根据需要添加其他查询条件
        queryWrapper.orderByDesc("id");
        
        // 调用 this.page 方法
        return this.page(page, queryWrapper);
    }

    default Long countById(Long id){
        return this.count(new QueryWrapper<T>().eq("id", id));
    }
    
    default boolean isEmpty(Long id){
        return countById(id) <= 0;
    }
    
    default boolean isNotEmpty(Long id){
        return !isEmpty(id);
    }

    default List<T> listByIn(List<Long> ids){
        if (ids.isEmpty()){
            return new ArrayList<>();
        }
        return this.list(new QueryWrapper<T>().in("id", ids));
    }

    default T findByMap(Map<String, Object> map) {
        return this.getOne(new QueryWrapper<T>().allEq(map).last("limit 1"));
    }

    default List<T> getBy(List<Object> values, String column){
        if (values.isEmpty()){
            return new ArrayList<>();
        }
        return this.list(new QueryWrapper<T>().in(column, values));
    }
    
    default T getBy(Object value, String column){
        if (Objects.isNull(value)){
            return null;
        }
        return this.getOne(new QueryWrapper<T>().eq(column, value).last("limit 1"));
    }
    
    default List<T> getListBy(Object value, String column){
        if (Objects.isNull(value)){
            return null;
        }
        return this.list(new QueryWrapper<T>().eq(column, value));
    }

    default T findBy(String value, String column){
        return this.getOne(new QueryWrapper<T>().eq(column, value).last("limit 1"));
    }
    
    // 构建 QueryWrapper
    default <U extends PageInput> QueryWrapper<T> buildQueryWrapper(Class<T> entityClass, U input) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        
        // 获取 T 类型的所有字段
        Field[] tFields = ReflectUtil.getFields(entityClass);
        
        // 遍历 T 类型的字段
        for (Field tField : tFields) {
            try {
                // 获取字段名称
                String fieldName = tField.getName();
    
                // 将驼峰命名转换为下划线分隔的数据库列名
                String columnName = StrUtil.toUnderlineCase(fieldName);
                
                // 根据字段名称获取 U 类型的字段
                Field uField = ReflectUtil.getField(input.getClass(), fieldName);
                
                // 如果在 U 类型中找到了相同名称的字段
                if (uField != null) {
                    // 设置字段可访问
                    ReflectUtil.setAccessible(tField);
                    ReflectUtil.setAccessible(uField);
                    
                    // 获取字段的值
                    Object value = ReflectUtil.getFieldValue(input, uField);
                    
                    // 根据字段类型添加查询条件
                    if (value != null) {
                        if (value instanceof String && StrUtil.isNotEmpty((String) value)) {
                            queryWrapper.like(true, columnName, value);
                        } else if (value instanceof Long) {
                            queryWrapper.eq(true, columnName, value);
                        } else if (value instanceof Boolean){
                            queryWrapper.eq(true, columnName, value);
                        }
                        // 可根据需要添加其他类型的判断
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        return queryWrapper;
    }
    
    default List<LabModel> getLabModels(QueryWrapper<T> queryWrapper) {
        if (queryWrapper == null) {
            return null;
        }
        
        // 调用 this.list 方法获取符合条件的实体对象列表
        List<T> entityList = this.list(queryWrapper);
        
        // 创建 LabModel 列表
        List<LabModel> labModels = new ArrayList<>();
        
        // 遍历实体对象列表，填充 LabModel 对象并加入到结果列表中
        for (T entity : entityList) {
            LabModel labModel = new LabModel();
            // 获取实体对象中的 id 和 name/title 字段的值
            Long id = getIdFromEntity(entity);
            String name = getNameOrTitleFromEntity(entity);
            // 设置 LabModel 对象的 id 和 name 字段的值
            labModel.setId(id);
            labModel.setName(name);
            labModels.add(labModel);
        }
        
        return labModels;
    }
    
    
    // 获取实体对象中的 id
    default Long getIdFromEntity(T entity) {
        try {
            // 获取实体对象的类对象
            Class<?> entityClass = this.getEntityClass();
            // 通过反射获取 id 字段的值
            Field idField = entityClass.getDeclaredField("id");
            idField.setAccessible(true); // 设置字段可访问
            return (Long) idField.get(entity);
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            return null;
        }
    }
    
    // 获取实体对象中的 name 或 title
    default String getNameOrTitleFromEntity(T entity) {
        try {
            // 获取实体对象的类对象
            Class<?> entityClass = this.getEntityClass();
            // 先尝试获取 name 字段的值
            Field nameField = entityClass.getDeclaredField("name");
            nameField.setAccessible(true); // 设置字段可访问
            String name = (String) nameField.get(entity);
            if (name != null) {
                return name;
            }
            // 如果 name 字段不存在或者值为空，则尝试获取 title 字段的值
            Field titleField = entityClass.getDeclaredField("title");
            titleField.setAccessible(true); // 设置字段可访问
            return (String) titleField.get(entity);
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            return null;
        }
    }
}
